package com.wjcxf.struct;


import java.util.ArrayList;
import java.util.List;

/**
 * @author 我叫程晓非
 * @desc PopStar
 * @date 2022-03-15
 * @version 1.0
 */
public class PopStar {
    public final static int ROW = 10;
    public final static int COL = 10;
    public final static int STATE_REMOVED = 0;
    public final static int STATE_NORMAL = 1;
    public final static int STATE_REMOVING = 2;

    public int score = 0;

    public ArrayList<Point> clickList = new ArrayList<>();

    public boolean isGameOver;
    public StarItem starItemArr[][] =new StarItem[ROW][COL];
    //构造方法1
    public PopStar(int[][] arr){
        for (int i = 0; i < ROW; i++){
            for (int j = 0; j < COL; j++){
                starItemArr[i][j] = new StarItem(arr[i][j]);
            }
        }
    }
    //构造方法2，这样就不用写深度克隆对象方法了
    public PopStar(PopStar popStar){
        this.score = popStar.score;
        this.isGameOver = popStar.isGameOver;
        for(int i=0;i< popStar.clickList.size();i++){
            this.clickList.add(new Point(popStar.clickList.get(i).getX(),popStar.clickList.get(i).getY()));
        }
        for (int i = 0; i < ROW; i++){
            for (int j = 0; j < COL; j++){
                starItemArr[i][j] = new StarItem(popStar.starItemArr[i][j].value);
            }
        }
    }


    public void resetVisited(){
        for (int i = 0; i < ROW; i++){
            for (int j = 0; j < COL; j++){
                if(starItemArr[i][j].state != STATE_REMOVED){
                    starItemArr[i][j].visited = false;
                    starItemArr[i][j].state = STATE_NORMAL;
                }
            }
        }
    }

    //检测是否游戏结束
    public boolean checkGameOver(){
        int startCount = 0;
        for (int i = 0; i < ROW; i++){
            for (int j = 0; j < COL; j++){
                if(virtualClick(i, j) >= 2){

                    return false;
                }
                if(this.starItemArr[i][j].value != 0){
                    ++startCount;
                }
            }
        }


        if(startCount <=9 && !isGameOver){
            this.score += (2000 - 20*startCount*startCount);
        }
        this.isGameOver = true;

        return true;
    }

    //检测是否要整列移动
    public void checkColMove(){
        int dt = 0;	//列的增量
        for (int i = 0; i < COL - dt; i++){
            boolean allRemoved = true;
            //检测某列是否整列为空
            for (int j = 0; j < ROW; j++){
                if(starItemArr[j][i].state != STATE_REMOVED){
                    allRemoved = false;
                    break;
                }
            }

            //开始移动列
            if(allRemoved){
                for (int x = i; x < COL; x++){
                    for (int y = 0; y < ROW; y++){
                        if(x + 1 < COL){
                            StarItem tempStarItem = starItemArr[y][x];
                            starItemArr[y][x] = starItemArr[y][x + 1];
                            starItemArr[y][x + 1] =tempStarItem;
                        }
                    }
                }
                //最后一列置空
                for (int y = 0; y < ROW; y++){
                    starItemArr[y][COL - 1].state = STATE_REMOVED;
                }
                i--;
                dt++;
            }
        }
    }
    //展开
    public List<Point> expansion(){
        List<Point> resultList = new ArrayList<>();
        for(int i=0;i<ROW;i++){
            for(int j=0;j<COL;j++){
                if(!starItemArr[i][j].visited && targetRemovingStar(i, j,0) >= 2){
                    resultList.add(new Point(i,j));
                }
            }
        }
        resetVisited();
        return resultList;
    }

    public void removeTargetStar(){
        for (int j = 0; j < COL; j++){
            for (int i = ROW-1; i >= 0; i--){
                if(starItemArr[i][j].state == STATE_REMOVING){
                    StarItem tempStar = starItemArr[i][j];
                    //依次把星星下移，并且把空的星星放到最上面
                    for (int x = i; x >= 0; x--)
                    {
                        if(x - 1 >= 0)
                        {starItemArr[x][j] = starItemArr[x - 1][j];}
                    }
                    starItemArr[0][j] = tempStar;
                    starItemArr[0][j].state = STATE_REMOVED;
                    starItemArr[0][j].value = 0;
                    i++;
                }
            }
        }
    }
    public int virtualClick(int x,int y){
        int clickCount = 0;
        clickCount = targetRemovingStar(x, y,clickCount);
        resetVisited();
        return clickCount;
    }
    //点击
    public int click(int x, int y){

        int targetCount = targetRemovingStar(x, y,0);
        if(targetCount == 1){
            starItemArr[x][y].visited = false;
        }

        if(targetCount >= 2){
            clickList.add(new Point(x,y));
            removeTargetStar();
            checkColMove();
            resetVisited();
            score += 5*targetCount*targetCount;

        }

//        System.out.println("click"+targetCount);

        return targetCount;
    }

    public int targetRemovingStar(int i, int j,  int clickCount){

        if(i >= ROW || i < 0 || j >= COL || j < 0 || starItemArr[i][j].state == STATE_REMOVED || starItemArr[i][j].visited || starItemArr[i][j].value == 0){
            return clickCount;
        }

        starItemArr[i][j].visited = true;
        clickCount++;

        //左
        if(i - 1 >= 0 && starItemArr[i - 1][j].state != STATE_REMOVED && starItemArr[i - 1][j].value == starItemArr[i][j].value){
            starItemArr[i][j].state = STATE_REMOVING;
            starItemArr[i - 1][j].state = STATE_REMOVING;
            clickCount = targetRemovingStar(i - 1, j, clickCount);
        }
        //右
        if(i + 1 < ROW && starItemArr[i + 1][j].state != STATE_REMOVED && starItemArr[i + 1][j].value == starItemArr[i][j].value){
            starItemArr[i][j].state = STATE_REMOVING;
            starItemArr[i + 1][j].state = STATE_REMOVING;
            clickCount = targetRemovingStar(i + 1, j, clickCount);
        }
        //上
        if(j + 1 < COL && starItemArr[i][j + 1].state != STATE_REMOVED && starItemArr[i][j + 1].value == starItemArr[i][j].value){
            starItemArr[i][j].state = STATE_REMOVING;
            starItemArr[i][j + 1].state = STATE_REMOVING;
            clickCount = targetRemovingStar(i, j + 1, clickCount);
        }
        //下
        if(j - 1 >= 0 && starItemArr[i][j - 1].state != STATE_REMOVED && starItemArr[i][j - 1].value == starItemArr[i][j].value){
            starItemArr[i][j].state = STATE_REMOVING;
            starItemArr[i][j - 1].state = STATE_REMOVING;
            clickCount =targetRemovingStar(i, j - 1, clickCount);
        }
        return clickCount;
    }

    public void showClickPath() {
        for(int i=0;i<this.clickList.size();i++){
            System.out.println(this.clickList.get(i).toString());
        }
    }

    class StarItem {
        int value;
        int state;
        boolean visited;

        public StarItem(int value){
            this.value = value;
            if(this.value == 0){
                this.state = STATE_REMOVED;
            }else{
                this.state = STATE_NORMAL;
            }

            this.visited = false;
        }
    }
    public void show(){
        System.out.println("=========score:"+this.score);
        for (int i = 0; i < ROW; i++){
            for (int j = 0; j < COL; j++){
                System.out.print(starItemArr[i][j].value+"\t");
            }
            System.out.println();
        }
    }
    //随机获取一个可能的位置
    public Point getRandomPosition(){
        List<Point> list = this.expansion();
        int randomIndex = (int)(Math.random()*100)%list.size();
        return list.get(randomIndex);
    }

}

